/**
 * Project Name:fire-industry-DM-center
 * File Name:DataSourcePrimaryConfig.java
 * Package Name:com.firestone.config.mybatis
 * Date:2018年3月13日下午3:18:40
 *
*/

package com.firestone.config.mybatis;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;

/**
 * @Description: TODO(第一数据源数据连接配置)
 * @author CAIYJ
 * @date 2018年3月13日 下午3:18:40
 */
@Configuration
@MapperScan(basePackages = "com.firestone.dao.primary", sqlSessionTemplateRef = "primarySqlSessionTemplate")
public class DataSourcePrimaryConfig {

    private static final Logger logger = LogManager
            .getLogger(DataSourcePrimaryConfig.class);

    @Bean(name = "primaryDataSource", initMethod = "init", destroyMethod = "close")
    @Primary
    public DruidDataSource dataSource(
            DruidConfigPrimaryProperties druidConfigPrimaryProperties)
                    throws SQLException {
        logger.info("初始化primaryDataSource");
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(
                druidConfigPrimaryProperties.getDriverClassName());
        druidDataSource.setUrl(druidConfigPrimaryProperties.getUrl());
        druidDataSource.setUsername(druidConfigPrimaryProperties.getUsername());
        druidDataSource.setPassword(druidConfigPrimaryProperties.getPassword());
        druidDataSource
                .setInitialSize(druidConfigPrimaryProperties.getMinIdle());
        druidDataSource.setMinIdle(druidConfigPrimaryProperties.getMinIdle());
        druidDataSource
                .setMaxActive(druidConfigPrimaryProperties.getMaxActive());
        druidDataSource.setMaxWait(druidConfigPrimaryProperties.getMaxWait());
        druidDataSource
                .setTimeBetweenEvictionRunsMillis(druidConfigPrimaryProperties
                        .getTimeBetweenEvictionRunsMillis());
        druidDataSource.setMinEvictableIdleTimeMillis(
                druidConfigPrimaryProperties.getMinEvictableIdleTimeMillis());
        druidDataSource.setValidationQuery(
                druidConfigPrimaryProperties.getValidationQuery());
        druidDataSource.setTestWhileIdle(
                druidConfigPrimaryProperties.getTestWhileIdle());
        druidDataSource.setTestOnBorrow(
                druidConfigPrimaryProperties.getTestOnBorrow());
        druidDataSource.setTestOnReturn(
                druidConfigPrimaryProperties.getTestOnReturn());
        druidDataSource.setPoolPreparedStatements(
                druidConfigPrimaryProperties.getPoolPreparedStatements());
        druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(
                druidConfigPrimaryProperties
                        .getMaxPoolPreparedStatementPerConnectionSize());
        druidDataSource.setFilters(druidConfigPrimaryProperties.getFilters());
        return druidDataSource;
    }

    @Bean(name = "primarySqlSessionFactory")
    @Primary
    public SqlSessionFactory sqlSessionFactory(
            @Qualifier("primaryDataSource") DataSource dataSource,
            GlobalConfiguration globalConfiguration) throws Exception {
        String mapperLocations = "classpath:mapper/primary/*.xml";
        String configLocation = "classpath:mybatis-sqlconfig.xml";
        String typeAliasesPackage = "com.firestone.bean.entity.mysql.primary";
        MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();
        // 数据源
        factory.setDataSource(dataSource);
        // 全局配置
        factory.setGlobalConfig(globalConfiguration);
        Interceptor[] interceptor = { new PaginationInterceptor() };
        // 分页插件
        factory.setPlugins(interceptor);
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        try {
            // 自动扫描Mapping.xml文件
            factory.setMapperLocations(resolver.getResources(mapperLocations));
            factory.setConfigLocation(resolver.getResource(configLocation));
            factory.setTypeAliasesPackage(typeAliasesPackage);
            return factory.getObject();
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    // MyBatis 动态扫描
    @Bean(name = "primaryMapperScannerConfigurer")
    public MapperScannerConfigurer mapperScannerConfigurer() {
        logger.info("初始化primaryMapperScannerConfigurer");
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        String basePackage = "com.firestone.dao.primary";
        mapperScannerConfigurer.setBasePackage(basePackage);
        return mapperScannerConfigurer;
    }

    @Bean(name = "primaryTransactionManager")
    @Primary
    public DataSourceTransactionManager transactionManager(
            @Qualifier("primaryDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "primarySqlSessionTemplate")
    @Primary
    public SqlSessionTemplate sqlSessionTemplate(
            @Qualifier("primarySqlSessionFactory") SqlSessionFactory sqlSessionFactory)
                    throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}
